package callme.ghost.vue;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Vector;

import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSlider;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.border.Border;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import callme.ghost.controler.CallmeControler;
import callme.ghost.model.CreateCall;
import callme.ghost.model.Model.Status;
import callme.ghost.observer.Observer;

/*
 * 
 * @author Anthony
 * 
 * 
 */

public class Affichage extends JFrame implements Observer {

	/**
	 * 
	 */
	private static final long serialVersionUID = 832749692041300111L;
	private CallmeControler cMc;
	private Vector<CreateCall> snapShot;
	private String tmp = "";

	private JPanel container = new JPanel();
	private JPanel east = new JPanel();
	private JPanel centre = new JPanel();
	private JPanel centerTop = new JPanel();
	private JPanel eastTopCover = new JPanel();
	private JPanel eastBottomCover = new JPanel();
	private JPanel buttonContainer = new JPanel();
	private JPanel volumeContainer = new JPanel();
	private JPanel northContainer = new JPanel();

	private JScrollPane eastTop = new JScrollPane(eastTopCover);
	private JScrollPane eastBottom = new JScrollPane(eastBottomCover);

	private JMenuBar menu = new JMenuBar();
	private JMenu menuFile = new JMenu("Menu");
	private JMenuItem menuFileCall = new JMenuItem("exit");
	private Border matteBorder = BorderFactory.createMatteBorder(2, 2, 2, 2,
			Color.magenta);
	private Border matteBorder2 = BorderFactory.createMatteBorder(2, 2, 2, 2,
			Color.blue);
	private Border lineBorder = BorderFactory.createLineBorder(Color.BLACK, 1);

	private JLabel north = new JLabel();
	private JTextArea ecran = new JTextArea();
	private JTextField ipCollector = new JTextField("147.171.79.166");

	private JButton callIp = new JButton("Appel");
	private JButton cancel = new JButton("Annule");
	private JSlider volume = new JSlider();

	private String[] tab_string = { "Accept", "Reject" };
	private String[] tab_string2 = { "Mute", "Hold", "End", "Info" };
	private JButton[] tab_button = new JButton[tab_string.length];
	private JButton[] tab_button2 = new JButton[tab_string2.length];
	private DynamicListener dynListener = new DynamicListener();

	private Dimension dim = new Dimension(405, 70);
	private Dimension dim2 = new Dimension(80, 20);
	// private Dimension dim3 = new Dimension(300, 150);
	private Dimension dim4 = new Dimension(650, 400);

	public Affichage(final CallmeControler cMc) {

		this.cMc = cMc;
		this.setSize(dim4);
		this.setTitle("Callme");
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setLocationRelativeTo(null);
		this.setResizable(false);
		initComposant();
		this.setContentPane(container);
		this.setJMenuBar(menu);
		this.setVisible(true);
	}

	private void initComposant() {
		Font police = new Font("Helvetica", Font.ITALIC, 15);
		Font police2 = new Font("Helvetica", Font.ITALIC, 12);

		container.setLayout(new BorderLayout());
		container.setBackground(Color.WHITE);
		container.add(centre, BorderLayout.CENTER);
		container.add(east, BorderLayout.EAST);
		container.add(northContainer, BorderLayout.NORTH);

		menu.setBackground(Color.cyan);
		// menuFileCall.set
		menu.add(menuFile);
		menuFile.add(menuFileCall);

		north.setFont(police);
		north.setHorizontalAlignment(JLabel.CENTER);
		north.setText("Logger ");
		// matteBorder = BorderFactory.createMatteBorder(5, 2, 5, 2,
		// Color.magenta);
		northContainer.setBorder(matteBorder);
		northContainer.add(north);

		centre.setLayout(new BorderLayout());
		centre.add(centerTop, BorderLayout.NORTH);
		centre.add(ecran, BorderLayout.CENTER);

		volume.setMaximum(10);
		volume.setMinimum(0);
		volume.setValue(5);
		volume.setMinorTickSpacing(1);
		volume.setMajorTickSpacing(5);
		// volume.setPaintTicks(true);
		// volume.setPaintLabels(true);
		// slide.addChangeListener(new Changed(this));
		// System.out.println(volume.getValue());

		centerTop.setLayout(new GridLayout(3, 1));
		centerTop.add(ipCollector);
		centerTop.add(buttonContainer);
		centerTop.add(volumeContainer);

		buttonContainer.setBackground(Color.yellow);
		buttonContainer.add(callIp);
		buttonContainer.add(cancel);
		volumeContainer.setBackground(Color.orange);
		volumeContainer.add(volume);
		ipCollector.setBorder(matteBorder2);
		ipCollector.setFont(police);
		ipCollector.setForeground(Color.gray);
		ipCollector.setHorizontalAlignment(JTextField.RIGHT);

		ecran.setEnabled(false);
		ecran.setBackground(Color.green);
		ecran.setFont(police2);
		ecran.setText("\nLa Description Audio ");

		east.setLayout(new GridLayout(2, 1, 5, 5));
		east.setPreferredSize(dim);
		east.setBackground(Color.pink);
		east.add(eastTop);
		east.add(eastBottom);

		// ////////////////////////////////////TRY ZONE BEGINS
		// eastTopCover.setLayout(new GridLayout(10,1,2,2));
		eastTopCover.setLayout(new BoxLayout(eastTopCover, BoxLayout.Y_AXIS));
		eastBottomCover.setLayout(new BoxLayout(eastBottomCover,
				BoxLayout.Y_AXIS));
		// eastBottomCover.setLayout(new GridLayout(10,1,2,2));
		// /////////////////////////////////// TRY ZONE ENDS

		cancel.addActionListener(new Cancel2BoutonListener());
		callIp.addActionListener(new CallBoutonListener());
		volume.addChangeListener(new SliderListener());
		menuFileCall.addActionListener(new MenuItemListener());

	}

	public void refreshCallList() {
		eastTopCover.removeAll();
		eastBottomCover.removeAll();

		eastTop.repaint();
		eastBottom.repaint();
		for (CreateCall appel : snapShot) {
			if (appel.getStatus() == Status.INCOMING) {// || appel.getStatus()
														// == Status.OUTGOING) {
				voirAppelEntrant(snapShot.indexOf(appel), appel);
			} else if (appel.getStatus() == Status.ACCEPTED
					|| appel.getStatus() == Status.WAITING) {
				voirAppelEnCours(snapShot.indexOf(appel), appel);
			}
		}
	}

	private void voirAppelEntrant(int id, CreateCall appel) {

		JPanel nBlock = new JPanel();
		JPanel nBlock2 = new JPanel();

		for (int i = 0; i < tab_string.length; i++) {
			tab_button[i] = new ButtonCall(tab_string[i], id, appel);
			tab_button[i].setPreferredSize(dim2);
			switch (i) {
			case 0:
				tab_button[i].addActionListener(dynListener);
				nBlock.add(tab_button[i]);
				break;

			case 1:
				tab_button[i].addActionListener(dynListener);
				nBlock.add(tab_button[i]);
				break;

			case 2:
				tab_button[i].addActionListener(dynListener);
				nBlock.add(tab_button[i]);
				break;

			default:
				System.out.println("error: the default case has been used");
				break;
			}

		}
		JLabel showCall = new JLabel(appel.getAddr().toString());
		nBlock2.add(showCall, BorderLayout.CENTER);
		nBlock2.add(nBlock, BorderLayout.EAST);
		nBlock2.setBorder(lineBorder);
		eastTopCover.add(nBlock2);
		eastTop.validate();
		eastTop.repaint();
	}

	private void voirAppelEnCours(int id, CreateCall appel) {
		JPanel sBlock = new JPanel();
		JPanel sBlock2 = new JPanel();

		for (int i = 0; i < tab_string2.length; i++) {
			tab_button2[i] = new ButtonCall(tab_string2[i], id, appel);
			tab_button2[i].setPreferredSize(dim2);
			switch (i) {
			case 0:
				tab_button2[i].addActionListener(dynListener);
				sBlock.add(tab_button2[i]);
				break;

			case 1:
				tab_button2[i].addActionListener(dynListener);
				sBlock.add(tab_button2[i]);
				break;

			case 2:
				tab_button2[i].addActionListener(dynListener);
				sBlock.add(tab_button2[i]);
				break;

			case 3:
				tab_button2[i].addActionListener(dynListener);
				sBlock.add(tab_button2[i]);
				break;

			case 4:
				tab_button2[i].addActionListener(dynListener);
				sBlock.add(tab_button2[i]);
				break;

			default:
				System.out.println("error: the default case has been used");
				break;
			}

		}
		JLabel showCall = new JLabel(appel.getAddr().toString());
		sBlock2.add(showCall, BorderLayout.CENTER);
		sBlock2.add(sBlock, BorderLayout.EAST);
		sBlock2.setBorder(lineBorder);
		eastBottomCover.add(sBlock2);
		eastBottom.validate();
		eastBottom.repaint();
	}

	public void printMsg(String bbc) {
		north.setText(bbc);
	}

	private void showInfo(String itv) {
		String[] parts = itv.split("\\,");
		if (parts.length != 7) {
			printMsg("the callers info is not yet available");
		}
		printMsg("");
		ecran.setText("\n\n\n\nLes dtails de l'appel :" + "\n\nRemote IP : "
				+ parts[0] + "\nRemote UDP port : " + parts[1]
				+ "\nSample Rate : " + parts[2] + "\nSample Size : " + parts[3]
				+ "\nChannels : " + parts[4] + "\nFrameSize : " + parts[5]
				+ "\nEndian : " + parts[6]);
	}

	private void showMesInfo(String ntn) {
		String[] parts = ntn.split("\\,");
		if (parts.length != 3) {
			printMsg("This info is not yet available");
		}
		printMsg("");
		ecran.setText("\n\n\n\nMes infoÉ :" + "\n\nLocal IP : "
				+ parts[0] + "\nLocal UDP port : " + parts[1]
				+ "\nLocal TCP port : " + parts[2]);
	}

	public CallmeControler getCmc() {
		return cMc;
	}

	// multiple controlers LoL
	public void setCmc(CallmeControler cmc) {
		this.cMc = cmc;
	}

	// ************************************************
	// IMPLEMENTATION THE LISTENERS
	// sub class pour Listiner
	// ************************************************

	private class Cancel2BoutonListener implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent arg0) {
			// TODO Auto-generated method stub
			// System.out.println("The Annule bouton has been pressed");
			cMc.cancelAppelEnCours();
		}

	}

	private class CallBoutonListener implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent arg0) {
			// TODO Auto-generated method stub
			// System.out.println("The Appel bouton has been pressed");
			if (cMc.makeCall(ipCollector.getText())) {
				ipCollector.setBackground(Color.GREEN);
			} else
				ipCollector.setBackground(Color.RED);
		}
	}

	private class SliderListener implements ChangeListener {

		@Override
		public void stateChanged(ChangeEvent arg0) {
			// TODO Auto-generated method stub
			if (!volume.getValueIsAdjusting()) {
				// int vol = (int) volume.getValue();
				// System.out.println("The volume is now set to :" + vol);
			}
		}
	}

	private class MenuItemListener implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent arg0) {
			// TODO Auto-generated method stub
			// System.out.println("The Exit bouton has been pressed");
			cMc.killAllCalls();
			System.exit(0);
		}

	}

	private class DynamicListener implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent e) {
			// TODO Auto-generated method stub
			String str = ((ButtonCall) e.getSource()).getText();
			cMc.dynKey(str, ((ButtonCall) e.getSource()).getAppel());
			if (((ButtonCall) e.getSource()).getText().startsWith("Mute")) {
				((ButtonCall) e.getSource()).setText("unmute");
			} else if (((ButtonCall) e.getSource()).getText().startsWith(
					"unmute")) {
				((ButtonCall) e.getSource()).setText("Mute");
			} else if (((ButtonCall) e.getSource()).getText()
					.startsWith("Hold")) {
				((ButtonCall) e.getSource()).setText("unhold");
			} else if (((ButtonCall) e.getSource()).getText().startsWith(
					"unhold")) {
				((ButtonCall) e.getSource()).setText("Hold");
			} else if (((ButtonCall) e.getSource()).getText()
					.startsWith("Info")) {
				tmp = cMc.getInfoTmp();
				showInfo(tmp);
			}

			// System.out.println("The " + str + " bouton has been pressed");
			// printMsg("The " + str + " bouton has been pressed"
			// + " button ID is: "
			// + ((ButtonCall) e.getSource()).getiDCall());
		}

	}

	// ************************************************
	// IMPLEMENTATION DU PATTERN OBSERVER
	// ************************************************
	@Override
	public void update(String str) {
		// TODO Auto-generated method stub
		this.snapShot = cMc.getListAppel();
		printMsg(str + " ");
		// initComposant();
		refreshCallList();
	}

}
